package roborally.model.executables;

import roborally.model.evaluables.Evaluable;

/**
 * A class implementing extending Executable, representing a loop. 
 * A loop consists of an Evaluable (the condition) and an Executable (the body).
 */
public class Loop extends Executable {
	private final Evaluable condition;
	private final Executable body;
	/**
	 * Constructs a Loop Executable with an Evualuable (the condition) and an Executable (the body). 
	 * @post The parameters are assigned to their instance variables.
	 */
	public Loop(Evaluable condition, Executable body){
		this.condition = condition;
		this.body = body;
	}

	@Override
	public boolean executeNextRobotCommand(RobotCommand lastExecutedRobotCommand){
		if( lastExecutedRobotCommand == null || (!this.contains(lastExecutedRobotCommand)) ){ //in case we dont contain last robotcommand, yet are executed, this means we are looking for the next robotcommand to execute!
			while(condition.evaluate()){
				if(body.executeNextRobotCommand(null)) return true;
			}
			return false;
		}
		else{ //lastExecutedRobotCommand != null && body.contains(lastExecutedRobotCommand
			//we bypass the condition
			if(body.executeNextRobotCommand(lastExecutedRobotCommand)) return true;
			return executeNextRobotCommand(null); //if the next robotcommand was not executed, we repeat the loop without a lastExecutedRobotCommand
		}
	}

	@Override
	public boolean contains(Executable other) {
		return body.contains(other);
	}
}
